Omandage SQLAlchemy hübriidomadused, et luua arvutatud atribuute ekspressiivsemate ja hooldatavamate andmemudelite jaoks. Õppige praktiliste näidetega.
Python SQLAlchemy Hübriidomadused: Arvutatud Atribuudid Võimsaks Andmemodelleerimiseks
SQLAlchemy, võimas ja paindlik Pythoni SQL-i tööriistakomplekt ja objekt-relatsiooniline vastendaja (ORM), pakub laia valikut funktsioone andmebaasidega suhtlemiseks. Nende hulgas paistavad Hübriidomadused silma eriti kasuliku tööriistana arvutatud atribuutide loomisel teie andmemudelites. See artikkel pakub põhjalikku juhendit SQLAlchemy hübriidomaduste mõistmiseks ja kasutamiseks, võimaldades teil luua ekspressiivsemaid, hooldatavamaid ja tõhusamaid rakendusi.
Mis on SQLAlchemy HĂĽbriidomadused?
Hübriidomadus, nagu nimestki võib järeldada, on SQLAlchemy eriline omaduste tüüp, mis võib käituda erinevalt sõltuvalt kontekstist, milles seda kasutatakse. See võimaldab teil määratleda atribuudi, mida saab otse kasutada teie klassi eksemplari peal (nagu tavalist omadust) või kasutada SQL-i avaldistes (nagu veergu). Seda saavutatakse, määratledes eraldi funktsioonid nii eksemplari- kui ka klassi tasemel juurdepääsuks.
Sisuliselt pakuvad hübriidomadused viisi arvutatud atribuutide määratlemiseks, mis on tuletatud teie mudeli muudest atribuutidest. Neid arvutatud atribuute saab kasutada päringutes ja neid saab otse kasutada teie mudeli eksemplaride peal, pakkudes ühtset ja intuitiivset liidest.
Miks kasutada hĂĽbriidomadusi?
HĂĽbriidomaduste kasutamine pakub mitmeid eeliseid:
- Ekspressiivsus: Need võimaldavad teil väljendada keerukaid seoseid ja arvutusi otse oma mudelis, muutes teie koodi loetavamaks ja kergemini mõistetavaks.
- Hooldatavus: Keerulise loogika kapseldades hübriidomadustesse, vähendate koodi dubleerimist ja parandate oma rakenduse hooldatavust.
- Tõhusus: Hübriidomadused võimaldavad teil arvutusi teha otse andmebaasis, vähendades teie rakenduse ja andmebaasiserveri vahel edastatava andmete hulka.
- Ühtsus: Need pakuvad ühtset liidest arvutatud atribuutidele juurdepääsuks, olenemata sellest, kas töötate oma mudeli eksemplaridega või kirjutate SQL-päringuid.
Põhiline näide: täisnimi
Alustame lihtsa näitega: isiku täisnime arvutamine tema ees- ja perekonnanime põhjal.
Mudeli määratlemine
Kõigepealt määratleme lihtsa Person mudeli first_name ja last_name veergudega.
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.hybrid import hybrid_property
Base = declarative_base()
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
def __repr__(self):
return f""
engine = create_engine('sqlite:///:memory:') # Näite jaoks mälusisene andmebaas
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
HĂĽbriidomaduse loomine
NĂĽĂĽd lisame full_name hĂĽbriidomaduse, mis ĂĽhendab ees- ja perekonnanime.
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
@hybrid_property
def full_name(self):
return f"{self.first_name} {self.last_name}"
def __repr__(self):
return f""
Selles näites muudab @hybrid_property dekorator full_name meetodi hübriidomaduseks. Kui pääsete juurde person.full_name, täidetakse selle meetodi sees olev kood.
Hübriidomadusele juurdepääs
Loome mõned andmed ja vaatame, kuidas full_name omadusele juurde pääseda.
person1 = Person(first_name='Alice', last_name='Smith')
person2 = Person(first_name='Bob', last_name='Johnson')
session.add_all([person1, person2])
session.commit()
print(person1.full_name) # Väljund: Alice Smith
print(person2.full_name) # Väljund: Bob Johnson
Hübriidomaduse kasutamine päringutes
Hübriidomaduste tõeline jõud avaldub nende kasutamisel päringutes. Saame filtreerida full_name alusel, nagu oleks see tavaline veerg.
people_with_smith = session.query(Person).filter(Person.full_name == 'Alice Smith').all()
print(people_with_smith) # Väljund: []
Siiski töötab ülaltoodud näide ainult lihtsate võrdlusoperatsioonide puhul. Keerukamate operatsioonide jaoks päringutes (nagu LIKE) peame määrama avaldifunktsiooni.
Avaldifunktsioonide määratlemine
Hübriidomaduste kasutamiseks keerukamates SQL-avaldistes peate määrama avaldifunktsiooni. See funktsioon ütleb SQLAlchemy-le, kuidas hübriidomadust SQL-avaldiseks teisendada.
Muudame eelmise näite, et toetada LIKE päringuid full_name omaduse kohta.
from sqlalchemy import func
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
@hybrid_property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@full_name.expression
def full_name(cls):
return func.concat(cls.first_name, ' ', cls.last_name)
def __repr__(self):
return f""
Siin lisasime @full_name.expression dekoratori. See määratleb funktsiooni, mis võtab argumendina klassi (cls) ja tagastab SQL-avaldise, mis ühendab ees- ja perekonnanime, kasutades funktsiooni func.concat. func.concat on SQLAlchemy funktsioon, mis tähistab andmebaasi ühendamisfunktsiooni (nt || SQLite'is, CONCAT MySQL-is ja PostgreSQL-is).
Nüüd saame kasutada LIKE päringuid:
people_with_smith = session.query(Person).filter(Person.full_name.like('%Smith%')).all()
print(people_with_smith) # Väljund: []
Väärtuste määramine: Setter
Hübriidomadustel võivad olla ka setterid, mis võimaldavad teil alusomadusi värskendada uue väärtuse põhjal. Seda tehakse @full_name.setter dekoratori abil.
Lisame full_name omadusele setter, mis jagab täisnime ees- ja perekonnanimeks.
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
@hybrid_property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@full_name.expression
def full_name(cls):
return func.concat(cls.first_name, ' ', cls.last_name)
@full_name.setter
def full_name(self, full_name):
parts = full_name.split()
self.first_name = parts[0]
self.last_name = ' '.join(parts[1:]) if len(parts) > 1 else ''
def __repr__(self):
return f""
Nüüd saate määrata full_name omaduse ja see värskendab first_name ja last_name atribuute.
person = Person(first_name='Alice', last_name='Smith')
session.add(person)
session.commit()
person.full_name = 'Charlie Brown'
print(person.first_name) # Väljund: Charlie
print(person.last_name) # Väljund: Brown
session.commit()
Deleterid
Sarnaselt setteritele saate määrata ka deleter'i hübriidomadusele @full_name.deleter dekoratori abil. See võimaldab teil määrata, mis juhtub, kui proovite kustutada del person.full_name.
Meie näite jaoks tühjendame täisnime kustutamisega nii ees- kui ka perekonnanime.
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
@hybrid_property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@full_name.expression
def full_name(cls):
return func.concat(cls.first_name, ' ', cls.last_name)
@full_name.setter
def full_name(self, full_name):
parts = full_name.split()
self.first_name = parts[0]
self.last_name = ' '.join(parts[1:]) if len(parts) > 1 else ''
@full_name.deleter
def full_name(self):
self.first_name = None
self.last_name = None
def __repr__(self):
return f""
person = Person(first_name='Charlie', last_name='Brown')
session.add(person)
session.commit()
del person.full_name
print(person.first_name) # Väljund: None
print(person.last_name) # Väljund: None
session.commit()
Täpsem näide: vanuse arvutamine sünnikuupäevast
Vaatame keerukamat näidet: isiku vanuse arvutamine sünnikuupäevast. See näitab hübriidomaduste võimsust kuupäevade töötlemisel ja arvutuste tegemisel.
Sünnikuupäeva veeru lisamine
Kõigepealt lisame meie Person mudelisse date_of_birth veeru.
from sqlalchemy import Date
import datetime
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
date_of_birth = Column(Date)
# ... (eelmine kood)
Vanuse arvutamine hĂĽbriidomadusega
Nüüd loome age hübriidomaduse. See omadus arvutab vanuse date_of_birth veeru põhjal. Peame käsitlema juhtumit, kus date_of_birth on None.
from sqlalchemy import Date
import datetime
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
date_of_birth = Column(Date)
@hybrid_property
def age(self):
if self.date_of_birth:
today = datetime.date.today()
age = today.year - self.date_of_birth.year - ((today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day))
return age
return None # Või muu vaikimisi väärtus
@age.expression
def age(cls):
today = datetime.date.today()
return func.cast(func.strftime('%Y', 'now') - func.strftime('%Y', cls.date_of_birth) - (func.strftime('%m-%d', 'now') < func.strftime('%m-%d', cls.date_of_birth)), Integer)
# ... (eelmine kood)
Olulised kaalutlused:
- Andmebaasispetsiifilised kuupäevafunktsioonid: Avaldifunktsioon kasutab kuupäevade arvutamiseks
func.strftime. See funktsioon on spetsiifiline SQLite'ile. Teiste andmebaaside (nagu PostgreSQL või MySQL) puhul peate kasutama vastavaid andmebaasispetsiifilisi kuupäevafunktsioone (ntEXTRACTPostgreSQL-is,YEARjaMAKEDATEMySQL-is). - Tüüpide teisendamine: Kasutame
func.castkuupäeva arvutuse tulemuse teisendamiseks täisarvuks. See tagab, etageomadus tagastab täisarvulise väärtuse. - Ajavööndid: Kuupäevadega töötades olge teadlik ajavöönditest. Veenduge, et teie kuupäevad oleksid salvestatud ja võrreldud ühtses ajavööndis.
Noneväärtuste käsitlemine: Omadus peaks käsitlema juhtumeid, kusdate_of_birthonNone, et vältida vigu.
Vanuse omaduse kasutamine
person1 = Person(first_name='Alice', last_name='Smith', date_of_birth=datetime.date(1990, 1, 1))
person2 = Person(first_name='Bob', last_name='Johnson', date_of_birth=datetime.date(1985, 5, 10))
session.add_all([person1, person2])
session.commit()
print(person1.age) # Väljund: (Põhineb praegusel kuupäeval ja sünnikuupäeval)
print(person2.age) # Väljund: (Põhineb praegusel kuupäeval ja sünnikuupäeval)
people_over_30 = session.query(Person).filter(Person.age > 30).all()
print(people_over_30) # Väljund: (30-aastased ja vanemad inimesed praeguse kuupäeva alusel)
Keerukamad näited ja kasutusjuhtumid
Tellimuste kogusummade arvutamine e-kaubanduse rakenduses
E-kaubanduse rakenduses võib teil olla Order mudel, millel on seos OrderItem mudelitega. Tellimuse koguväärtuse arvutamiseks võite kasutada hübriidomadust.
from sqlalchemy import ForeignKey, Float
from sqlalchemy.orm import relationship
class Order(Base):
__tablename__ = 'orders'
id = Column(Integer, primary_key=True)
items = relationship("OrderItem", back_populates="order")
@hybrid_property
def total(self):
return sum(item.price * item.quantity for item in self.items)
@total.expression
def total(cls):
return session.query(func.sum(OrderItem.price * OrderItem.quantity)).
filter(OrderItem.order_id == cls.id).scalar_subquery()
class OrderItem(Base):
__tablename__ = 'order_items'
id = Column(Integer, primary_key=True)
order_id = Column(Integer, ForeignKey('orders.id'))
order = relationship("Order", back_populates="items")
price = Column(Float)
quantity = Column(Integer)
See näide demonstreerib keerukamat avaldifunktsiooni, kasutades alampäringut kogusumma arvutamiseks otse andmebaasis.
Geograafilised arvutused
Kui töötate geograafiliste andmetega, võite kasutada hübriidomadusi punktide vaheliste kauguste arvutamiseks või selle kindlaksmääramiseks, kas punkt on teatud piirkonnas. See hõlmab sageli andmebaasispetsiifiliste geograafiliste funktsioonide kasutamist (nt PostGIS-i funktsioonid PostgreSQL-is).
from geoalchemy2 import Geometry
from sqlalchemy import cast
class Location(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
name = Column(String)
coordinates = Column(Geometry(geometry_type='POINT', srid=4326))
@hybrid_property
def latitude(self):
if self.coordinates:
return self.coordinates.x
return None
@latitude.expression
def latitude(cls):
return cast(func.ST_X(cls.coordinates), Float)
@hybrid_property
def longitude(self):
if self.coordinates:
return self.coordinates.y
return None
@longitude.expression
def longitude(cls):
return cast(func.ST_Y(cls.coordinates), Float)
See näide nõuab geoalchemy2 laiendust ja eeldab, et kasutate PostGIS-iga lubatud andmebaasi.
HĂĽbriidomaduste kasutamise parimad tavad
- Hoidke seda lihtsana: Kasutage hübriidomadusi suhteliselt lihtsate arvutuste jaoks. Keerukama loogika jaoks kaaluge eraldi funktsioonide või meetodite kasutamist.
- Kasutage sobivaid andmetĂĽĂĽpe: Veenduge, et teie hĂĽbriidomadustes kasutatavad andmetĂĽĂĽbid ĂĽhilduksid nii Pythoni kui ka SQL-iga.
- Kaaluge jõudlust: Kuigi hübriidomadused võivad parandada jõudlust, tehes arvutusi andmebaasis, on oluline jälgida oma päringute jõudlust ja neid vajadusel optimeerida.
- Testige põhjalikult: Testige oma hübriidomadusi põhjalikult, et tagada nende õigete tulemuste saamine kõigis kontekstides.
- Dokumenteerige oma kood: Dokumenteerige oma hübriidomadused selgelt, et selgitada, mida need teevad ja kuidas need töötavad.
Levinud lõksud ja kuidas neid vältida
- Andmebaasispetsiifilised funktsioonid: Veenduge, et teie avaldifunktsioonid kasutavad andmebaasist sõltumatuid funktsioone või pakuvad andmebaasispetsiifilisi rakendusi, et vältida ühilduvusprobleeme.
- Vigased avaldifunktsioonid: Kontrollige hoolikalt, et teie avaldifunktsioonid teisendavad teie hübriidomaduse õigesti kehtivaks SQL-avaldiseks.
- Jõudluse pudelikaelad: Vältige hübriidomaduste kasutamist liiga keerukate või ressursimahukate arvutuste jaoks, kuna see võib põhjustada jõudluse pudelikaelu.
- Nimeristumised: Vältige hübriidomaduse ja oma mudeli veeru sama nimega nimetamist, kuna see võib põhjustada segadust ja vigu.
Rahvusvahelise suhtluse kaalutlused
Rahvusvahelise suhtlusega rakendustes hübriidomadustega töötades kaaluge järgmist:
- Kuupäeva- ja kellaajavormingud: Kasutage erinevate lokalite jaoks sobivaid kuupäeva- ja kellaajavorminguid.
- Numbriformaadid: Kasutage erinevate lokalite jaoks sobivaid numbriformaate, sealhulgas koma- ja tuhandeeraldajaid.
- Valuutaformaadid: Kasutage erinevate lokalite jaoks sobivaid valuutaformaate, sealhulgas valuutasĂĽmboleid ja kĂĽmnendkohti.
- Tekstivõrdlused: Kasutage lokaliteadlikke tekstivõrdlusfunktsioone, et tagada tekstide õige võrdlemine erinevates keeltes.
Näiteks vanuse arvutamisel võtke arvesse erinevaid maailmas kasutusel olevaid kuupäevavorminguid. Mõnes piirkonnas kirjutatakse kuupäev kui MM/DD/YYYY, samas kui teistes kui DD/MM/YYYY või YYYY-MM-DD. Veenduge, et teie kood töötleb kuupäevi kõigis vormingutes õigesti.
Tekstide ühendamisel (nagu full_name näites) olge teadlik nime järjekorra kultuurierinevustest. Mõnes kultuuris eelneb perekonnanimi eesnimele. Kaaluge valikute pakkumist kasutajatele, et kohandada nime kuvamisvormingut.
Järeldus
SQLAlchemy hübriidomadused on võimas tööriist arvutatud atribuutide loomiseks teie andmemudelites. Need võimaldavad teil väljendada keerukaid seoseid ja arvutusi otse oma mudelites, parandades koodi loetavust, hooldatavust ja tõhusust. Hübriidomaduste, avaldifunktsioonide, setterite ja deleterite määratlemise mõistmisega saate seda funktsiooni kasutada keerukamate ja vastupidavamate rakenduste loomiseks.
Järgides selles artiklis kirjeldatud parimaid tavasid ja vältides levinud lõkse, saate hübriidomadusi tõhusalt kasutada oma SQLAlchemy mudelite täiustamiseks ja andmepääsu loogika lihtsustamiseks. Pidage meeles, et arvestage rahvusvahelise suhtluse aspektidega, et tagada oma rakenduse korrektne toimimine kasutajatele üle maailma. Hoolika planeerimise ja rakendamise abil võivad hübriidomadused muutuda teie SQLAlchemy tööriistakomplekti hindamatuks osaks.